package it.gestionedocumentale.spring.service;

import java.util.List;

import org.hibernate.Transaction;
import org.springframework.beans.BeanUtils;

import it.gestionedocumentale.hibernate.dao.ProfiloDAO;
import it.gestionedocumentale.hibernate.dao.UtenteDAO;
import it.gestionedocumentale.hibernate.sessionfactory.HibernateSessionFactory;
import it.gestionedocumentale.model.Gruppo;
import it.gestionedocumentale.model.Profilo;
import it.gestionedocumentale.model.Utente;
import it.gestionedocumentale.struts.form.UtenteForm;

public class UtenteServiceImpl implements UtenteService {
	
	private UtenteDAO utenteDAO;
	private ProfiloDAO profiloDAO;
	
	public void setUtenteDAO(UtenteDAO utenteDAO) {
		this.utenteDAO = utenteDAO;
	}

	public UtenteDAO getUtenteDAO() {
		return utenteDAO;
	}
	
	public void setProfiloDAO(ProfiloDAO profiloDAO) {
		this.profiloDAO = profiloDAO;
	}

	public ProfiloDAO getProfiloDAO() {
		return profiloDAO;
	}

	@Override
	public void save(Utente transientInstance) throws Exception {
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		utenteDAO.save(transientInstance);
		tx.commit();
	}

	@Override
	public void delete(Utente persistentInstance) throws Exception {
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		utenteDAO.delete(persistentInstance);
		tx.commit();
		
	}

	@Override
		public void update(UtenteForm utenteForm) throws Exception {
		Gruppo gruppo = MyServiceFactory.getGruppoService().findById(utenteForm.getIdGruppo());
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		Utente utenteDaModificare = utenteDAO.findById(utenteForm.getIdUtente());
		Profilo profiloDaModificare = profiloDAO.findById(utenteDaModificare.getProfilo().getIdProfilo());
		BeanUtils.copyProperties(utenteForm, profiloDaModificare);
		BeanUtils.copyProperties(utenteForm, utenteDaModificare);
		// prendo la password dal form di modifica e chiamo il metodo per l'MD5.
		String hashPasswordFornita = md5hash(utenteForm.getPassword());
		// setto nell'utente da modificare la password criptata
		utenteDaModificare.setPassword(hashPasswordFornita);
		utenteDaModificare.setGruppo(gruppo);
		tx.commit();
	}
	
	@Override
	public Utente findById(Long idUtente) throws Exception {
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		Utente result = utenteDAO.findById(idUtente);
		tx.commit();
		return result;
	}
	
	@Override
	public void cancellazioneLogica(Long idUtente) throws Exception {
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		Utente utente = utenteDAO.findById(idUtente);
		utente.setAttivo("NO");
		tx.commit();
		
	}

	@Override
	public List<Utente> findByExample(Utente instance) throws Exception {
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		List<Utente> result = utenteDAO.findByExample(instance);
		tx.commit();
		return result;
	}

	@Override
	public List<Utente> findAll() throws Exception {
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		List<Utente> results = utenteDAO.findAll();
		tx.commit();
		return results;
	}

	
	/*
	 * (non-Javadoc)
	 * @see it.gestionedocumentale.spring.service.UtenteService#findByLoginAndPassword(java.lang.String, java.lang.String)
	 * conversione della password in MD5;
	 */
	
	@Override
	public Utente findByLoginAndPassword(String login, String password) throws Exception {
		String hashPasswordFornita = md5hash(password);
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		Utente utente = utenteDAO.findByLoginAndPassword(login, hashPasswordFornita);
		tx.commit();
		return utente;
	}
	
	@Override
	public List<Utente> cercaUtente(UtenteForm utenteForm) throws Exception {
		Utente utenteExample = new Utente();
		
		BeanUtils.copyProperties(utenteForm, utenteExample);
		
//		String hashPasswordFornita = md5hash(utenteForm.getPassword());
//		utenteExample.setPassword(hashPasswordFornita);
		
		if (utenteForm.getIdGruppo()!=null) {
			utenteExample.setGruppo(MyServiceFactory.getGruppoService()
					.findById(utenteForm.getIdGruppo()));
		}
		
		Profilo profiloExample = new Profilo();
		BeanUtils.copyProperties(utenteForm, profiloExample);
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		List<Utente> utenti = utenteDAO.searchUtente(utenteExample, profiloExample);
		tx.commit();
		return utenti.size() < 1 ? null : utenti;
	}
	
	@Override
	public void inserisciNuovoUtente(UtenteForm utenteForm) throws Exception {
		Profilo profiloDaInserire = new Profilo();
		BeanUtils.copyProperties(utenteForm, profiloDaInserire);
		MyServiceFactory.getProfiloService().save(profiloDaInserire);
		Utente utenteDaInserire = new Utente();
		org.springframework.beans.BeanUtils.copyProperties(utenteForm, utenteDaInserire);
		
		// chiamata al metodo dell'md5
		String hashPasswordFornita = md5hash(utenteForm.getPassword());
		utenteDaInserire.setPassword(hashPasswordFornita);
		
		utenteDaInserire.setGruppo(MyServiceFactory.getGruppoService().findById(utenteForm.getIdGruppo()));
		utenteDaInserire.setProfilo(profiloDaInserire);
		save(utenteDaInserire);
	}
	
	//il metodo fa un controllo sulla login e ritorna false se la login 
	//inserita è già esistente
	@Override
	public boolean controllaLoginUtente(UtenteForm utenteForm) throws Exception {
		Utente utente = new Utente();
		utente.setLogin(utenteForm.getLogin());
		utente.setIdUtente(utenteForm.getIdUtente());
		List<Utente> lista = utenteDAO.controllaLogin(utente);
		return lista != null && lista.size()>0?false:true;
	}

	@Override
	public List<Utente> findAllActive() throws Exception {
		Transaction tx = HibernateSessionFactory.getSession().beginTransaction();
		List<Utente> results = utenteDAO.findByAttivo("SI");
		tx.commit();
		return results;
	}
	
	/*
	 * metodo privato per criptare tramite l'MD5 la password.
	 * per ora è un metodo privato dell'implementazione del Service dell'Utente.
	 */
	
	 private String md5hash(String password) {
	        String hashString = null;
	        try {
	            java.security.MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
	            byte[] hash = digest.digest(password.getBytes());
	            hashString = "";
	            for (int i = 0; i < hash.length; i++) {
	                hashString += Integer.toHexString( 
	                                  (hash[i] & 0xFF) | 0x100 
	                              ).toLowerCase().substring(1,3);
	            }
	        } catch (java.security.NoSuchAlgorithmException e) {
	            System.out.println(e);
	        }
	        return hashString;
	    }
	

}
